package com.system.mongodb.service;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.system.mongodb.entity.Comment;
import com.system.mongodb.entity.Publish;
import com.system.mongodb.enums.CommentType;
import com.system.mongodb.enums.IdType;
import com.system.mongodb.util.RedisUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class LabService {



    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdService idService;
    @Autowired
    private RedisTemplate mongodbRedisTemplate;
    /**
     * 发布动态
     *
     * @param publish
     * @return 发布成功返回动态id
     */
    public String savePublish(Publish publish) {
        //对publish对象校验
        if (!ObjectUtil.isAllNotEmpty(publish.getText(), publish.getUserId())) {
            //发布失败
            return null;
        }

        //设置主键id
        publish.setId(ObjectId.get());

        try {
            //设置自增长的pid
            publish.setPid(this.idService.createId(IdType.PUBLISH));
            publish.setCreated(System.currentTimeMillis());

            //写入到publish表中
            this.mongoTemplate.save(publish);

        } catch (Exception e) {
            //TODO 需要做事务的回滚，Mongodb的单节点服务，不支持事务，对于回滚我们暂时不实现了
            log.error("发布动态失败~ publish = " + publish, e);
        }
        return publish.getId().toHexString();
    }
    public Publish queryPublishById(String id) {
        return this.mongoTemplate.findById(new ObjectId(id), Publish.class);
    }

    public Boolean likeComment(Long userId, String publishId) {
        //判断该⽤户是否已经点赞，如果已经点赞就直接返回
        if (this.queryUserIsLike(userId, publishId)) {
            return false;
        }

        //保存Comment数据
        Boolean result = this.saveComment(userId, publishId, CommentType.LIKE,
                null);
        if (!result) {
            return false;
        }

        //修改redis中的点赞数以及是否点赞

        //修改点赞数
        String redisKey = RedisUtil.getCommentRedisKeyPrefix(publishId);
        String hashKey = CommentType.LIKE.toString();
        mongodbRedisTemplate.opsForHash().increment(redisKey, hashKey, 1);

        //⽤户是否点赞
        String userHashKey = RedisUtil.getCommentUserLikeRedisKeyPrefix(userId);
        mongodbRedisTemplate.opsForHash().put(redisKey, userHashKey, "1");

        return true;
    }



    public Boolean queryUserIsLike(Long userId, String publishId) {
        //从redis中查询数据
        String redisKey = RedisUtil.getCommentRedisKeyPrefix(publishId);
        String userHashKey = RedisUtil.getCommentUserLikeRedisKeyPrefix(userId);
        Object data = mongodbRedisTemplate.opsForHash().get(redisKey, userHashKey);
        if (ObjectUtil.isNotEmpty(data)) {
            return StrUtil.equals(Convert.toStr(data), "1");
        }

        //查询Mongodb，确定是否已经点赞
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId)
                .and("commentType").is(CommentType.LIKE)
        );
        long count = this.mongoTemplate.count(query, Comment.class);
        if (count == 0) {
            return false;
        }

        //写入到redis中
        mongodbRedisTemplate.opsForHash().put(redisKey, userHashKey, "1");

        return true;
    }

    /**
     * 保存Comment
     *
     * @return
     */
    private Boolean saveComment(Long userId, String publishId,
                                CommentType commentType, String content) {
        try {
            Comment comment = new Comment();
            comment.setId(ObjectId.get());
            comment.setUserId(userId);
            comment.setPublishId(new ObjectId(publishId));
            // 评论类型
            comment.setCommentType(commentType.getType());
            // 内容
            comment.setContent(content);
            comment.setCreated(System.currentTimeMillis());

            Publish publish = this.queryPublishById(publishId);
            if (ObjectUtil.isNotEmpty(publish)) {
                comment.setPublishUserId(publish.getUserId());
            } else {
                //查询评论
                Comment myComment = this.queryCommentById(publishId);
                if(ObjectUtil.isNotEmpty(myComment)){
                    comment.setPublishUserId(myComment.getUserId());
                }else{
                    //TODO 其他情况，比如小视频等
                }
            }

            this.mongoTemplate.save(comment);

            return true;
        } catch (Exception e) {
            log.error("保存Comment出错~ userId = " + userId + ", publishId = " + publishId + ", commentType = " + commentType, e);
        }

        return false;
    }

    private Comment queryCommentById(String id) {
        return this.mongoTemplate.findById(new ObjectId(id), Comment.class);
    }

}
